#include "pdeVolume.h"
#include "volume_utils.h"

namespace pde {

	std::shared_ptr<VolumeShort> VolumeShort::New() {
		return std::make_shared<VolumeShort>();
	}
	std::shared_ptr<VolumeUChar> VolumeUChar::New() {
		return std::make_shared<VolumeUChar>();
	}
	std::shared_ptr<VolumeFloat> VolumeFloat::New() {
		return std::make_shared<VolumeFloat>();
	}

	bool VolumeShort::Create(short default_val, short* voxels) {
		if (voxels_!=nullptr) {
			delete[] voxels_; voxels_ = nullptr;
		}

		int length = size_[0] * size_[1] * size_[2];

		if (length != 0)
		{
			voxels_ = new short[length];

			if (voxels)
				memcpy(voxels_, voxels, length * sizeof(short));
			else
			{
				for (int k = 0; k < length; k++)
					voxels_[k] = default_val;
			}
			return true;
		}
		return false;
	};

	bool VolumeShort::Create(Size size,Spacing spacing,Origin origin, short default_val, short* pixels)
	{
		size_ = size;
		spacing_ = spacing;
		origin_ = origin;
		return Create(default_val, pixels);
	}

	bool VolumeUChar::Create(unsigned char default_val, unsigned char* voxels) {
		if (voxels_!=nullptr) {
			delete[] voxels_; voxels_ = nullptr;
		}

		int length = size_[0] * size_[1] * size_[2];

		if (length != 0)
		{
			voxels_ = new unsigned char[length];

			if (voxels)
				memcpy(voxels_, voxels, length * sizeof(char));
			else
			{
				for (int k = 0; k < length; k++)
					voxels_[k] = default_val;
			}
			return true;
		}
		return false;
	};

	bool VolumeUChar::Create(Size size,Spacing spacing,Origin origin, unsigned char default_val, unsigned char* pixels)
	{
		size_ = size;
		spacing_ = spacing;
		origin_ = origin;
		return Create(default_val, pixels);
	}

	bool VolumeFloat::Create(float default_val, float* voxels) {
		if (voxels_!=nullptr) {
			delete[] voxels_; voxels_ = nullptr;
		}

		int length = size_[0] * size_[1] * size_[2];

		if (length != 0)
		{
			voxels_ = new float[length];

			if (voxels)
				memcpy(voxels_, voxels, length * sizeof(float));
			else
			{
				for (int k = 0; k < length; k++)
					voxels_[k] = default_val;
			}
			return true;
		}
		return false;
	};

	bool VolumeFloat::Create(Size size,Spacing spacing,Origin origin, float default_val,float* pixels)
	{
		size_ = size;
		spacing_ = spacing;
		origin_ = origin;
		return Create(default_val, pixels);
	}

}


namespace pde {

	//---------------------------------------------------------------------------------------------------------
	


	void VolumeShort::save_volume(const std::string& fn) {
		save_volume_mhd<short>(voxels_, size_, spacing_, origin_, fn, "");
	}

	void VolumeShort::load_volume(const std::string& fn) {
		std::string v;
		load_mhd_header(fn, size_, spacing_, origin_, v);
		Create(size_, spacing_, origin_);
		load_mhd_volume(voxels_, fn);

	}
	void VolumeFloat::save_volume(const std::string& fn) {
		save_volume_mhd<float>(voxels_, size_, spacing_, origin_, fn, "");
	}

	void VolumeFloat::load_volume(const std::string& fn) {
		std::string v;
		load_mhd_header(fn, size_, spacing_, origin_, v);
		Create(size_, spacing_, origin_);
		load_mhd_volume(voxels_, fn);

	}

	void VolumeUChar::save_volume(const std::string& fn, const std::string& info) {

		save_volume_mhd<unsigned char>(voxels_, size_, spacing_, origin_, fn, info);
	}

	std::string VolumeUChar::load_volume(const std::string& fn) {
		std::string v;
		load_mhd_header(fn, size_, spacing_, origin_, v);
		Create(size_, spacing_, origin_);
		load_mhd_volume(voxels_, fn);
		return v;
	}
	std::shared_ptr<DoseCurve> DoseCurve::New() {
		return std::make_shared<DoseCurve>();
		}

}